﻿using AutoMapper;
using Domain.Material_Management;
using Domain.Production_Modules;
using Domain.QualityInspection_Modelling;
using Infratructure.Interface;
using MediatR;
using MES.Server.API.Application.Command.QualityInspection_ModCom;
using MES.Server.API.Dto.QualityInspection_DTO;
using Microsoft.EntityFrameworkCore;
using ReturnValue;
using Yitter.IdGenerator;

namespace MES.Server.API.Application.Handler.QualityInspection_ModHandler.NewQualityInspectionCommandHandler
{
    /// <summary>
    /// 质检记录添加命令处理器
    /// </summary>
    public class QualityInspectionCreateCommandHandlers : IRequestHandler<QualityInspectionCreateCommands, ApiResult<int>>
    {
        private readonly IMapper _mapper;
        private readonly IRepository<QualityInspection> _qualityRepo;
        private readonly IRepository<ProduceModel> _produceRepo; // 用于验证生产工单合法性

        public QualityInspectionCreateCommandHandlers(
            IMapper mapper,
            IRepository<QualityInspection> qualityRepo,
            IRepository<ProduceModel> produceRepo)
        {
            _mapper = mapper;
            _qualityRepo = qualityRepo;
            _produceRepo = produceRepo;
        }

        public async Task<ApiResult<int>> Handle(QualityInspectionCreateCommands request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();

            #region 1. 基础参数验证
            // 验证必填字段
            if (request.ProductionOrderId <= 0)
                return result.Fail("关联生产工单ID不能为空");
            if (request.MaterialGroupId <= 0)
                return result.Fail("关联物料群组ID不能为空");
            if (request.InspectedQuantity <= 0)
                return result.Fail("检测数量必须大于0");
            if (request.QualifiedQuantity < 0 || request.QualifiedQuantity > request.InspectedQuantity)
                return result.Fail($"合格数量必须在0到{request.InspectedQuantity}之间");
            if (string.IsNullOrWhiteSpace(request.Inspector))
                return result.Fail("检测人员不能为空");
            if (string.IsNullOrWhiteSpace(request.CreaterPeople))
                return result.Fail("创建人不能为空");


            // 新增：判断该生产工单是否已存在未删除的质检记录（避免重复添加）
            var isDuplicate = await _qualityRepo.GetAll()
                .AnyAsync(q => q.ProductionOrderId == request.ProductionOrderId && !q.IsDel, cancellationToken);
            if (isDuplicate)
                return result.Fail($"生产工单（ID：{request.ProductionOrderId}）已存在质检记录，不可重复添加");

            // 验证生产工单合法性（需为已完成工单，且物料群组ID匹配）
            var production = await _produceRepo.GetValue(request.ProductionOrderId);
            if (production == null)
                return result.Fail("关联的生产工单不存在");
            if (production.ProduceNum != production.FinishProduceNum)
                return result.Fail("仅允许对生产完成率100%的工单创建质检记录");
            if (production.MaterialGroupId != request.MaterialGroupId)
                return result.Fail("物料群组ID与生产工单关联的群组ID不匹配");
            #endregion

            #region 2. 实体映射与字段赋值
            // 映射Command到质检实体
            var qualityInspection = _mapper.Map<QualityInspection>(request);

            // 自动生成主键（参考ProduceCreateCommand的YitIdHelper）
            qualityInspection.Id = YitIdHelper.NextId();

            // 生成质检单号（格式：QI+日期+3位随机数，与ProduceCode生成逻辑一致）
            var dateStr = DateTime.Now.ToString("yyyyMMdd");
            var randomNum = new Random().Next(100, 999);
            qualityInspection.InspectionNumber = $"QI{dateStr}{randomNum}";

            // 自动计算不合格数量
            qualityInspection.UnqualifiedQuantity = request.InspectedQuantity - request.QualifiedQuantity;

            // 审计字段赋值（参考ProduceCreateCommand）
            qualityInspection.CreateTime = DateTime.Now; // AuditEntity默认字段
            qualityInspection.CreaterPeople = request.CreaterPeople; // AuditEntity默认字段
            qualityInspection.IsDel = false; // AuditEntity默认字段（逻辑删除标识）
            qualityInspection.UpdaterPeople = null; // 初始无修改人
            qualityInspection.UpdateTime = null; // 初始无修改时间
            #endregion

            #region 3. 数据保存
            var dbResult = await _qualityRepo.AddAsync(qualityInspection);
            if (dbResult > 0)
            {
                // 参考ProduceCreateCommand的AddSuccess逻辑
                result = result.AddSuccess("质检记录", dbResult);
            }
            else
            {
                result = result.AddFail("质检记录");
            }
            result.Data = dbResult; // 返回受影响行数
            #endregion

            return await Task.FromResult(result);
        }
    }
}
